<?php

namespace App\Service\Cruise\Check;

use App\Enums\BaseErrorCode;
use App\Exceptions\Custom\ResponseHttpException;
use App\Library\Rms\RmsShopApi;
use App\Models\Common\ResourcesModel;
use App\Models\Cruise\CruiseCheckAgainstModel;
use App\Models\Cruise\CruiseCheckAgainstShopMappingModel;
use App\Models\Cruise\CruiseCheckDetailModel;
use App\Models\Cruise\CruiseCheckErrorModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Scope\Shop\ShopScope;
use App\Service\BaseService;
use App\Service\OpenShop\User\RmsUserService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class CruiseCheckErrorsService extends BaseService
{

    /**
     * 列表
     * @param string $startTime
     * @param string $endTime
     * @param string $invalidType
     * @param int $dealUid
     * @param int $pageSize
     * @param int $pageNum
     * @return array
     * @throws GuzzleException
     */
    public static function lists(string $startTime, string $endTime, string $invalidType, int $dealUid, int $pageSize, int $pageNum, string $status): array
    {
        $paginator = CruiseCheckErrorModel::query()
            ->whereIn('invalidType', [CruiseCheckErrorModel::INVALID_TYPE_STOP, CruiseCheckErrorModel::INVALID_TYPE_REJECT])
            ->with(['cruiseCheckDetailRel', 'userIdentityCardRel'])
            ->when(
                $startTime, function ($query) use ($startTime) {
                $query->where('createdAt', '>=', strtotime($startTime));
            }
            )
            ->when(
                $endTime, function ($query) use ($endTime) {
                $query->where('createdAt', '<', strtotime($endTime) + 86400);
            }
            )
            ->when(
                $invalidType > 0, function ($query) use ($invalidType) {
                $query->where('invalidType', $invalidType);
            }
            )
            ->when(
                ShopScope::getShopIdsArr(), function ($query) {
                $query->whereIn("shopId", ShopScope::getShopIdsArr());
            }
            )
            ->when(
                $dealUid > 0, function ($query) use ($dealUid) {
                $query->whereRaw("cruiseCheckDetailId in (select `id` from `cruise_check_details` where `dealUid` = $dealUid)");
            }
            )
            ->when(
                $status != "", function ($query) use ($status) {
                $query->where('status', (int)$status);
            }
            )
            ->orderByDesc('id')
            ->paginate($pageSize, ['*'], 'pageNum', $pageNum);
        $shopIds   = collect($paginator->items())->pluck('shopId')->toArray();
        //门店信息
        $shopInfo    = (new RmsShopApi())->getShopByIds($shopIds, ['id', 'shopCode', 'name'])['data']['shopList'] ?? [];
        $shopList    = array_column($shopInfo, null, 'id');
        $dealUserIds = collect($paginator->items())->pluck('dealUid')->toArray();
        $userInfos   = collect(RmsUserService::getRmsUserInfoByUserIds($dealUserIds)['data'])->keyBy('id');
        $lists       = $paginator->map(
            function (CruiseCheckErrorModel $cruiseCheckErrorModel) use ($userInfos, $shopList) {
                return [
                    'id'           => $cruiseCheckErrorModel->id,
                    'shopId'       => $cruiseCheckErrorModel->shopId,
                    'shopCode'     => $shopList[$cruiseCheckErrorModel->shopId]['shopCode'] ?? '-',
                    'shopName'     => $shopList[$cruiseCheckErrorModel->shopId]['name'] ?? '-',
                    'merchantName' => $cruiseCheckErrorModel->userIdentityCardRel->count() ? $cruiseCheckErrorModel->userIdentityCardRel[0]->name : '-',
                    'invalidType'  => $cruiseCheckErrorModel->invalidType,
                    'dealName'     => optional($cruiseCheckErrorModel->cruiseCheckDetailRel)->dealName,
                    'createdAt'    => $cruiseCheckErrorModel->createdAt->toDateTimeString(),
                    'status'       => $cruiseCheckErrorModel->status,
                    'dealResult'   => $cruiseCheckErrorModel->dealResult,
                    'manageName'   => $userInfos[$cruiseCheckErrorModel->dealUid]['username'] ?? '',
                    'dealTime'     => formatDate($cruiseCheckErrorModel->dealTime),
                ];
            }
        );

        return [
            'pageNum'   => $paginator->currentPage(),
            'pageSize'  => $paginator->perPage(),
            'pageCount' => ceil($paginator->total() / $paginator->perPage()),
            'count'     => $paginator->total(),
            'lists'     => $lists,
        ];
    }


    /**
     * 详情
     * @param int $id
     * @return array
     * @throws GuzzleException
     */
    public static function detail(int $id): array
    {
        $info = CruiseCheckErrorModel::query()->with(['cruiseCheckDetailRel', 'cruiseCheckAgainstRel', 'resourcesRel'])->find($id);
        if (!$info) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "不存在的异常报备单id");
        }
        $shopIds         = [$info['shopId']];
        $shopInfos       = collect((new RmsShopApi())->getShopByIds($shopIds, ['id', 'shopCode', 'name'])['data']['shopList'] ?? [])->keyBy('id');
        $shopCodes       = $shopInfos->pluck('shopCode');
        $merchantUserIds = OpenShopSignOrderModel::query()
            ->whereIn('shopCode', $shopCodes)
            ->orderByDesc('id')
            ->select('shopCode', 'merchantUserId')
            ->get()
            ->keyBy('shopCode');

        $merchantUserIds = $merchantUserIds->pluck('merchantUserId')->toArray();
        $userInfos       = collect(RmsUserService::getRmsUserInfoByUserIds(array_merge($merchantUserIds, [$info['dealUid']]))['data'])->keyBy('id');
        $shopCode        = $shopInfos[$info['shopId'] ?? 0]['shopCode'] ?? '';

        $dealInfo = $resourcesList = [];
        if ($info->cruiseCheckAgainstRel) {
            $dealInfo = [
                "id"           => optional($info->cruiseCheckAgainstRel)->id ?? 0,
                "level"        => optional($info->cruiseCheckAgainstRel)->level ?? 0,
                "serialNum"    => optional($info->cruiseCheckAgainstRel)->serialNum ?? "",
                "type"         => optional($info->cruiseCheckAgainstRel)->type ? explode(',', optional($info->cruiseCheckAgainstRel)->type) : "",
                "price"        => optional($info->cruiseCheckAgainstRel)->price ? formatPrice(optional($info->cruiseCheckAgainstRel)->price) : 0,
                "behaviorDesc" => optional($info->cruiseCheckAgainstRel)->behaviorDesc ?? 0,
                "rectifyPlan"  => optional($info->cruiseCheckAgainstRel)->rectifyPlan ?? 0,
                'version'      => optional($info->cruiseCheckAgainstRel)->version ?? "",
            ];
        }
        collect($info->resourcesRel)->each(
            function (ResourcesModel $resourcesModel) use (&$resourcesList) {
                $resourcesList[] = picturePath($resourcesModel->url);

            }
        )->toArray();

        return [
            'id'               => $info['id'],
            'shopId'           => $info['shopId'],
            'shopCode'         => $shopCode,
            'shopName'         => $shopInfos[$info['shopId'] ?? 0]['name'] ?? '',
            'merchantName'     => $userInfos[$merchantUserIds[$shopCode]['merchantUserId'] ?? 0]['username'] ?? '',
            'invalidType'      => $info['invalidType'],
            'createdAt'        => $info['createdAt']->toDateTimeString(),
            'status'           => $info['status'],
            'dealResult'       => $info['dealResult'],
            'conditionExplain' => $info['conditionExplain'],
            'dealTime'         => formatDate($info['dealTime']),
            'manageName'       => $userInfos[$info['dealUid']]['username'] ?? '',
            'dealInfo'         => $dealInfo,     //违约函详情
            'resourcesList'    => $resourcesList,//视频资源
        ];
    }


    /**
     * 处理
     * @param int $id
     * @param $request
     * @param int $price
     * @throws Exception
     */
    public static function edit(int $id, $request, $price = 0)
    {
        $info = CruiseCheckErrorModel::query()->find($id);
        if (!$info) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "不存在的异常报备单id");
        }

        if ($info['dealResult'] != CruiseCheckErrorModel::DEAL_RESULT_UNTREATED) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "已处理的异常报备单无法处理");
        }

        try {
            DB::beginTransaction();
            $data = [
                'dealResult'      => $request->dealResult,
                'status'          => CruiseCheckErrorModel::STATUS_COMMIT,
//                'againstLevel'    => $request->level,
//                'againstCategory' => $request->type,
                'dealUid'         => getRmsUserId(),
                'dealTime'        => time(),
            ];
            CruiseCheckErrorModel::setCheckErrorsInfoById($id, $data);
            if ($request->dealResult == CruiseCheckErrorModel::DEAL_RESULT_BREACH_LETTER) {//开具违约函
                CruiseCheckAgainstService::addCheckAgainst(
                    $info['shopId'], $price, $request->level, $request->type, $info['cruiseCheckDetailId'],
                    CruiseCheckAgainstModel::BUSINESS_TYPE_ERROR, $id, $request->behaviorDesc, $request->rectifyPlan
                    , CruiseCheckAgainstModel::TEMPLATE_TYPE_DEFAULT, strtotime($info['createdAt'])
                );
            }
            DB::commit();
        } catch (Exception $e) {
            DB::rollBack();
            handleException($e);
        }
    }

}
